﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.IO;
using System.Windows.Forms;

namespace ComicsEditor
{
    public partial class Form1 : Form
    {
        string defaultPath = Path.GetDirectoryName(Application.ExecutablePath);
        ComicInfo comicInfo = new ComicInfo();
        PageInfo pageInfo;

        public Form1()
        {
            InitializeComponent();
            System.Windows.Forms.Application.Idle += new EventHandler(OnApplicationIdle);
        }

        private void OnApplicationIdle(object sender, System.EventArgs e)
        {
            int previewIndex = comicInfo != null ? comicInfo.GetNextPreview() : -1;
            if (previewIndex >= 0)
            {
                imageListPreview.Images.Add(comicInfo[previewIndex].Preview);
                listViewPages.Items[previewIndex].ImageIndex = imageListPreview.Images.Count - 1;
            }
        }

        private void LoadComicInfo(ComicInfo newComicInfo)
        {
            pageEditor.Reset();
            if (comicInfo != null)
                comicInfo.Close();
            comicInfo = newComicInfo;

            toolStrip1.Visible = false;
            pageControl.Visible = false;

            pageInfo = null;
            listViewPages.Items.Clear();
            imageListPreview.Images.Clear();

            for (int i = 0; i < comicInfo.Count; i++)
                listViewPages.Items.Add(new ListViewItem());
            UpdateNames();
        }

        public void UpdateNames()
        {
            SortedList<string, int> types = new SortedList<string,int>();
            for (int i = 0; i < comicInfo.Count; i++)
            {
                string type = comicInfo[i].Type;
                if (type == "")
                    type = "Page";
                if (types.ContainsKey(type))
                    types[type]++;
                else
                    types.Add(type, 1);
                comicInfo[i].ViewName = type + " " + types[type];
                listViewPages.Items[i].Text = comicInfo[i].ViewName;
            }
        }

        private void openXmlToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openXmlDialog.ShowDialog() == DialogResult.OK)
            {
                LoadComicInfo(new ComicInfo(new ReaderFolder(Path.GetDirectoryName(openXmlDialog.FileName), Path.GetFileName(openXmlDialog.FileName))));
                defaultPath = Path.GetDirectoryName(openXmlDialog.FileName);
            }
        }

        private void openFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.SelectedPath == "")
                folderBrowserDialog1.SelectedPath = defaultPath;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                LoadComicInfo(new ComicInfo(new ReaderFolder(folderBrowserDialog1.SelectedPath, "ComicInfo.xml")));
                defaultPath = folderBrowserDialog1.SelectedPath;
            }
        }

        private void openPackageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                LoadComicInfo(new ComicInfo(new ReaderPackage(openFileDialog1.FileName)));
                defaultPath = Path.GetDirectoryName(openFileDialog1.FileName);
            }
        }

        private void saveInfoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveXmlDialog.FileName = openXmlDialog.FileName;
            if (saveXmlDialog.ShowDialog() == DialogResult.OK)
            {
                comicInfo.SaveInfo(saveXmlDialog.FileName);
                defaultPath = Path.GetDirectoryName(saveXmlDialog.FileName);
            }
        }

        private void saveFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                comicInfo.Save(new WriterFolder(folderBrowserDialog1.SelectedPath));
                defaultPath = folderBrowserDialog1.SelectedPath;
            }
        }

        private void savePackageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = openFileDialog1.FileName;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                comicInfo.Save(new WriterPackage(saveFileDialog1.FileName));
                defaultPath = Path.GetDirectoryName(saveFileDialog1.FileName);
            }
        }

        private void listViewPages_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listViewPages.SelectedIndices.Count > 0)
            {
                int i = listViewPages.SelectedIndices[0];

                if (pageInfo != null)
                    pageInfo.Image = null;
                pageInfo = comicInfo[i];
                pageInfo.Image = comicInfo.GetImage(i);

                toolStrip1.Visible = pageInfo.Page != null;
                if (pageInfo.Page != null)
                    pageEditor.SetPageInfo(pageInfo);
                else
                    pageEditor.Reset();
                balloonControl.Bind(pageInfo);
                frameControl.Bind(pageInfo);
                textControl.Bind(pageInfo);
                pageControl.Bind(pageInfo);
                toolStripComboBoxScale.Text = (int)(100*pageEditor.Scale) + "%";
            }
        }

        private void toolStripButtonZoomIn_Click(object sender, EventArgs e)
        {
            pageEditor.Scale *= 2;
            toolStripComboBoxScale.Text = (int)(100*pageEditor.Scale) + "%";
        }

        private void toolStripButtonZoomOut_Click(object sender, EventArgs e)
        {
            pageEditor.Scale *= 0.5f;
            toolStripComboBoxScale.Text = (int)(100*pageEditor.Scale) + "%";
        }

        private void toolStripButtonOne_Click(object sender, EventArgs e)
        {
            pageEditor.Scale = pageEditor.Size.Height/(float)pageEditor.Page.Height;
            toolStripComboBoxScale.Text = (int)(100*pageEditor.Scale) + "%";
        }

        private void toolStripButtonWide_Click(object sender, EventArgs e)
        {
            pageEditor.Scale = pageEditor.Size.Width/(float)pageEditor.Page.Width;
            toolStripComboBoxScale.Text = (int)(100*pageEditor.Scale) + "%";
        }

        private void toolStripButtonActual_Click(object sender, EventArgs e)
        {
            pageEditor.Scale = 1;
            toolStripComboBoxScale.Text = "100%";
        }

        private void toolStripComboBoxScale_Validated(object sender, EventArgs e)
        {
            int i = 0;
            while (i < toolStripComboBoxScale.Text.Length && Char.IsDigit(toolStripComboBoxScale.Text, i))
                i++;
            pageEditor.Scale = int.Parse(toolStripComboBoxScale.Text.Substring(0, i))/100f;
            toolStripComboBoxScale.Text = (int)(100*pageEditor.Scale) + "%";
        }

        private void toolStripComboBoxScale_SelectedIndexChanged(object sender, EventArgs e)
        {
            toolStripComboBoxScale_Validated(sender, e);
        }

        private void toolStripButtonBalloon_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloon.Checked)
            {
                toolStripButtonFrame.Checked = false;
                toolStripButtonText.Checked = false;
                balloonControl.Activate(pageEditor);
            }
            else
            {
                balloonControl.Disactivate();
            }
        }

        private void toolStripButtonFrame_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonFrame.Checked)
            {
                toolStripButtonBalloon.Checked = false;
                toolStripButtonText.Checked = false;
                frameControl.Activate(pageEditor);
            }
            else
            {
                frameControl.Disactivate();
            }
        }

        private void toolStripButtonText_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonText.Checked)
            {
                toolStripButtonFrame.Checked = false;
                toolStripButtonBalloon.Checked = false;
                textControl.Activate(pageEditor);
            }
            else
            {
                textControl.Disactivate();
            }
        }

        private void toolStripButtonImageAdd_Click(object sender, EventArgs e)
        {
            if (openImageDialog.ShowDialog() == DialogResult.OK)
            {
                foreach (string fileName in openImageDialog.FileNames)
                {
                    comicInfo.AddPage(fileName);
                    listViewPages.Items.Add(new ListViewItem());
                }
                UpdateNames();
            }
        }

        private void toolStripButtonImageRemove_Click(object sender, EventArgs e)
        {
            while (listViewPages.SelectedIndices.Count > 0)
            {
                int i = listViewPages.SelectedIndices[0];
                listViewPages.Items.RemoveAt(i);
                comicInfo.RemovePage(i);
            }
            UpdateNames();
            pageEditor.Reset();
            toolStrip1.Visible = false;
            pageControl.Visible = false;
            pageInfo = null;
        }

        private void toolStripButtonImageUp_Click(object sender, EventArgs e)
        {
            if (listViewPages.SelectedIndices.Count > 0)
            {
                int i = listViewPages.SelectedIndices[0];

                if (i > 0)
                {
                    comicInfo.SwapPages(i, i - 1);
                    int temp = listViewPages.Items[i].ImageIndex;
                    listViewPages.Items[i].ImageIndex = listViewPages.Items[i - 1].ImageIndex;
                    listViewPages.Items[i - 1].ImageIndex = temp;
                    UpdateNames();
                    listViewPages.SelectedIndices.Clear();
                    listViewPages.SelectedIndices.Add(i - 1);
                }
            }
        }

        private void toolStripButtonImageDown_Click(object sender, EventArgs e)
        {
            if (listViewPages.SelectedIndices.Count > 0)
            {
                int i = listViewPages.SelectedIndices[0];

                if (i < comicInfo.Count - 1)
                {
                    comicInfo.SwapPages(i, i + 1);
                    int temp = listViewPages.Items[i].ImageIndex;
                    listViewPages.Items[i].ImageIndex = listViewPages.Items[i + 1].ImageIndex;
                    listViewPages.Items[i + 1].ImageIndex = temp;
                    UpdateNames();
                    listViewPages.SelectedIndices.Clear();
                    listViewPages.SelectedIndices.Add(i + 1);
                }
            }
        }

        private void toolStripButtonMetadata_Click(object sender, EventArgs e)
        {
            MetadataDialog dialog = new MetadataDialog();
            dialog.ComicInfo = comicInfo;
            dialog.ShowDialog();
        }

        private void batchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BatchDialog dialog = new BatchDialog();
            dialog.ComicInfo = comicInfo;
            dialog.ShowDialog(this);
            if (pageInfo != null)
                pageControl.Bind(pageInfo);
        }

        public void AddEmptyPage()
        {
            comicInfo.AddPage(null);
            listViewPages.Items.Add(new ListViewItem());
            UpdateNames();
            listViewPages.SelectedIndices.Clear();
            listViewPages.SelectedIndices.Add(comicInfo.Count - 1);
        }

        private void addEmptyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddEmptyPage();
        }

        private void renderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RenderDialog dialog = new RenderDialog();
            dialog.ComicInfo = comicInfo;
            dialog.DefaultPath = defaultPath;
            dialog.ShowDialog(this);
        }
    }
}